/*     */ package com.zimbra.cs.servlet;
/*     */ 
/*     */ import com.google.common.base.Joiner;
/*     */ import com.zimbra.common.service.ServiceException;
/*     */ import com.zimbra.common.util.Log;
/*     */ import com.zimbra.common.util.StringUtil;
/*     */ import com.zimbra.common.util.ZimbraLog;
/*     */ import com.zimbra.cs.account.AuthToken;
/*     */ import com.zimbra.cs.account.Config;
/*     */ import com.zimbra.cs.account.CsrfTokenKey;
/*     */ import com.zimbra.cs.account.Provisioning;
/*     */ import com.zimbra.cs.servlet.util.CsrfUtil;
/*     */ import com.zimbra.soap.RequestContext;
/*     */ import java.io.IOException;
/*     */ import java.net.MalformedURLException;
/*     */ import java.util.Arrays;
/*     */ import java.util.Enumeration;
/*     */ import java.util.List;
/*     */ import java.util.Random;
/*     */ import javax.servlet.Filter;
/*     */ import javax.servlet.FilterChain;
/*     */ import javax.servlet.FilterConfig;
/*     */ import javax.servlet.ServletException;
/*     */ import javax.servlet.ServletRequest;
/*     */ import javax.servlet.ServletResponse;
/*     */ import javax.servlet.http.HttpServletRequest;
/*     */ import javax.servlet.http.HttpServletResponse;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public class CsrfFilter
/*     */   implements Filter
/*     */ {
/*     */   public static final String CSRF_SALT = "CSRF_SALT";
/*  57 */   private String[] allowedRefHosts = null;
/*     */   public static final String AUTH_TOKEN = "AuthToken";
/*     */   public static final String CSRF_TOKEN_CHECK = "CsrfTokenCheck";
/*     */   protected int maxCsrfTokenValidityInMs;
/*  61 */   private Random nonceGen = null;
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public void init(FilterConfig filterConfig)
/*     */     throws ServletException
/*     */   {
/*  71 */     Provisioning prov = Provisioning.getInstance();
/*     */     try {
/*  73 */       this.allowedRefHosts = prov.getConfig().getCsrfAllowedRefererHosts();
/*  74 */       this.nonceGen = new Random();
/*  75 */       CsrfTokenKey.getCurrentKey();
/*  76 */       if (ZimbraLog.misc.isInfoEnabled()) {
/*  77 */         ZimbraLog.misc.info("CSRF filter was initialized: CSRFAllowedRefHost: [" + Joiner.on(", ").join(this.allowedRefHosts) + "]");
/*     */       }
/*     */     }
/*     */     catch (ServiceException e) {
/*  81 */       throw new ServletException("Error initializing CSRF filter: " + e.getMessage(), e);
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public void destroy()
/*     */   {
/*  95 */     ZimbraLog.filter.info("Destroying CSRF filter.");
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
/*     */     throws IOException, ServletException
/*     */   {
/* 108 */     ZimbraLog.clearContext();
/*     */     
/* 110 */     HttpServletRequest req = (HttpServletRequest)request;
/* 111 */     HttpServletResponse resp = (HttpServletResponse)response;
/* 112 */     req.setAttribute("CSRF_SALT", Integer.valueOf(this.nonceGen.nextInt() + 1));
/*     */     
/* 114 */     if (ZimbraLog.misc.isDebugEnabled()) {
/* 115 */       ZimbraLog.misc.debug("CSRF Request URI: " + req.getRequestURI());
/*     */     }
/*     */     
/* 118 */     boolean csrfCheckEnabled = Boolean.FALSE.booleanValue();
/* 119 */     boolean csrfRefererCheckEnabled = Boolean.FALSE.booleanValue();
/* 120 */     Provisioning prov = Provisioning.getInstance();
/*     */     try {
/* 122 */       csrfCheckEnabled = prov.getConfig().isCsrfTokenCheckEnabled();
/* 123 */       csrfRefererCheckEnabled = prov.getConfig().isCsrfRefererCheckEnabled();
/*     */     } catch (ServiceException e) {
/* 125 */       ZimbraLog.misc.info("Error in CSRF filter." + e.getMessage(), e);
/*     */     }
/*     */     
/* 128 */     if (ZimbraLog.misc.isDebugEnabled()) {
/* 129 */       ZimbraLog.misc.debug("CSRF filter was initialized : CSRFcheck enabled: " + csrfCheckEnabled + "CSRF referer check enabled: " + csrfRefererCheckEnabled + ", CSRFAllowedRefHost: [" + Joiner.on(", ").join(this.allowedRefHosts) + "]" + ", CSRFTokenValidity " + this.maxCsrfTokenValidityInMs + "ms.");
/*     */     }
/*     */     
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/* 136 */     if (ZimbraLog.misc.isTraceEnabled()) {
/* 137 */       Enumeration<String> hdrNames = req.getHeaderNames();
/* 138 */       ZimbraLog.misc.trace("Soap request headers.");
/* 139 */       while (hdrNames.hasMoreElements()) {
/* 140 */         String name = (String)hdrNames.nextElement();
/*     */         
/* 142 */         if (!name.contains("Cookie"))
/*     */         {
/* 144 */           ZimbraLog.misc.trace(name + "=" + req.getHeader(name));
/*     */         }
/*     */       }
/*     */     }
/* 148 */     if ((csrfRefererCheckEnabled) && 
/* 149 */       (!allowReqBasedOnRefererHeaderCheck(req))) {
/* 150 */       ZimbraLog.misc.info("CSRF referer check failed");
/* 151 */       resp.sendError(403);
/* 152 */       return;
/*     */     }
/*     */     
/*     */ 
/* 156 */     if (!csrfCheckEnabled) {
/* 157 */       req.setAttribute("CsrfTokenCheck", Boolean.FALSE);
/* 158 */       chain.doFilter(req, resp);
/*     */     } else {
/* 160 */       req.setAttribute("zimbraCsrfTokenCheckEnabled", Boolean.TRUE);
/* 161 */       AuthToken authToken = CsrfUtil.getAuthTokenFromReq(req);
/* 162 */       if (CsrfUtil.doCsrfCheck(req, authToken))
/*     */       {
/* 164 */         req.setAttribute("CsrfTokenCheck", Boolean.TRUE);
/*     */       } else {
/* 166 */         req.setAttribute("CsrfTokenCheck", Boolean.FALSE);
/* 167 */         ZimbraLog.misc.debug("CSRF check will not be done for URI : %s", new Object[] { req.getRequestURI() });
/*     */       }
/* 169 */       chain.doFilter(req, resp);
/*     */     }
/*     */     
/*     */ 
/*     */     try
/*     */     {
/* 175 */       RequestContext reqCtxt = new RequestContext();
/* 176 */       String host = CsrfUtil.getRequestHost(req);
/* 177 */       reqCtxt.setVirtualHost(host);
/* 178 */       ZThreadLocal.setContext(reqCtxt);
/*     */     }
/*     */     finally
/*     */     {
/* 182 */       ZThreadLocal.unset();
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   protected static List<String> convertToList(String urlList)
/*     */   {
/* 192 */     List<String> urls = null;
/* 193 */     if (!StringUtil.isNullOrEmpty(urlList)) {
/* 194 */       String[] temp = urlList.split(",");
/* 195 */       for (int i = 0; i < temp.length; i++) {
/* 196 */         temp[i] = temp[i].toLowerCase();
/*     */       }
/* 198 */       urls = Arrays.asList(temp);
/*     */     }
/* 200 */     return urls;
/*     */   }
/*     */   
/*     */   private boolean allowReqBasedOnRefererHeaderCheck(HttpServletRequest req)
/*     */   {
/*     */     try
/*     */     {
/* 207 */       if (CsrfUtil.isCsrfRequestBasedOnReferrer(req, this.allowedRefHosts)) {
/* 208 */         return false;
/*     */       }
/*     */     } catch (MalformedURLException e) {
/* 211 */       ZimbraLog.misc.info("Error while doing referer based check." + e.getMessage());
/* 212 */       return false;
/*     */     }
/* 214 */     return true;
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/servlet/CsrfFilter.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */